2019_mohr_algorithmic_modulations.py

#

SPDX-FileCopyrightText: 2019 Timothée Gignac & Nicolas Schiltz SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be

SPDX-License-Identifier: GPL-3.0-or-later

#

-- coding:Utf8 --

#

Manfred Mohr # Timothée GIGNAC, Nicolas SCHILTZ # 24.01.2020 # Blender 2.8 # Windows 10 #

import bpy
import random
import math
#

Delete all objects

bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete(use_global=False, confirm=False)
#

Operations

cube_gen = bpy.ops.mesh.primitive_cube_add
resize = bpy.ops.transform.resize
translate = bpy.ops.transform.translate
rand = random.uniform
sqrt = math.sqrt
#

Values setup

#

Proximity between each cubes in chains

prox_x_min = 10
prox_x_max = 12
prox_y_min = 10
prox_y_max = 12
prox_z_min = -6
prox_z_max = 6
#

Limits

x_min = 10
x_max = 90
y_min = 10
y_max = 90
#

Bottom

z_min_bot = 5
z_max_bot = 25
#

Top

z_min_top = 75
z_max_top = 95
#

Number of cubes per group

c_num = 7
#

Generating cubes and columns

#

Defining how cubes can be generated one after the other

#
def makeGroup(coord_1):

    c_size = 9  # size of the first cube
    coord_1  # generating the first cube
    cube_gen(size=c_size, location=coord_1)

    for i in range(c_num):  # setting conditions for the next cube to be generated

        x, y, z = coord_1

        x1 = x + rand(prox_x_min, prox_x_max) * random.choice([-1, 1])
        while not (x_min < x1 and x1 < x_max):
            x1 = x + rand(prox_x_min, prox_x_max) * random.choice([-1, 1])

        y1 = y + rand(prox_y_min, prox_y_max) * random.choice([-1, 1])
        while not (y_min < y1 and y1 < y_max):
            y1 = y + rand(prox_y_min, prox_y_max) * random.choice([-1, 1])

        z1 = z + rand(prox_z_min, prox_z_max) * random.choice([-1, 1])
        while not (z_min_bot < z1 and z1 < z_max_bot) and not (
            z_min_top < z1 and z1 < z_max_top
        ):
            z1 = z + rand(prox_z_min, prox_z_max) * random.choice([-1, 1])

        coord_2 = (x1, y1, z1)
        hypo = sqrt((x1 - x) ** 2 + (y1 - y) ** 2)
        resize_factor = max(
            [sqrt(hypo**2 - (x1 - x) ** 2), sqrt(hypo**2 - (y1 - y) ** 2)]
        )
        c_size_v = (
            resize_factor - c_size / 2
        ) * 2  # the next cube's size will now be adjusted to touch the previous cube's face

        cube_gen(
            size=c_size_v, location=coord_2
        )  # generating the second cube, allowing the chain to go on

        if z1 < z_max_bot:  # generating a column for each cube
            cube_gen(size=1, location=coord_2)
            resize(value=(2, 2, z1))
            translate(value=(0, 0, (z1 / 2) + c_size_v / 2))

        if z1 > z_min_top:
            cube_gen(size=1, location=coord_2)
            resize(value=(2, 2, 100 - z1))
            translate(value=(0, 0, -c_size_v / 2 - (100 - z1) / 2))

        c_size = (
            c_size_v  # allowing cubes to follow each other one face againt the other
        )
        coord_1 = coord_2  # allowing cubes to be generated one after the other

    return coord_2
#

Making the chains

#
def makeClouds(n):

    c_size = 9
    coord_1 = (c_size / 2, c_size / 2, rand(z_min_bot, z_max_bot))
    coord_3 = (100 - c_size / 2, c_size / 2, rand(z_min_bot, z_max_bot))
    coord_5 = (c_size / 2, 100 - c_size / 2, rand(z_min_bot, z_max_bot))
    coord_7 = (100 - c_size / 2, 100 - c_size / 2, rand(z_min_bot, z_max_bot))
    columns = []

    for i in range(n):  # chain 1
        x2, y2, z2 = makeGroup(coord_1)
        columns.append((x2, y2, z2))
        coord_2 = (x2, y2, rand(z_min_top, z_max_top))
        columns.append(coord_2)

        x3, y3, z3 = makeGroup(coord_2)
        coord_1 = (x3, y3, rand(z_min_bot, z_max_bot))

    for i in range(n):  # chain 2
        x2, y2, z2 = makeGroup(coord_3)
        columns.append((x2, y2, z2))
        coord_4 = (x2, y2, rand(z_min_top, z_max_top))
        columns.append(coord_4)

        x3, y3, z3 = makeGroup(coord_4)
        coord_3 = (x3, y3, rand(z_min_bot, z_max_bot))

    for i in range(n):  # chain 3
        x2, y2, z2 = makeGroup(coord_5)
        columns.append((x2, y2, z2))
        coord_6 = (x2, y2, rand(z_min_top, z_max_top))
        columns.append(coord_6)

        x3, y3, z3 = makeGroup(coord_6)
        coord_5 = (x3, y3, rand(z_min_bot, z_max_bot))

    for i in range(n):  # chain 4
        x2, y2, z2 = makeGroup(coord_7)
        columns.append((x2, y2, z2))
        coord_8 = (x2, y2, rand(z_min_top, z_max_top))
        columns.append(coord_8)

        x3, y3, z3 = makeGroup(coord_8)
        coord_7 = (x3, y3, rand(z_min_bot, z_max_bot))

    return columns


sticks = makeClouds(1)  # number of interlinked groups generated, per pairs of two
#

Generating the structural columns

for coord in sticks[::2]:
    x, y, z = coord
    cube_gen(size=2, location=(x, y, 0))
    resize(value=(1, 1, 50))
    translate(value=(0, 0, 50))